local key = KEYS[1]
local consumeToken = tonumber(ARGV[1])
local curTime = tonumber(ARGV[2])
local maxBurst = tonumber(ARGV[3])
local rate = tonumber(ARGV[4])
local ratelimitInfo = redis.call("HMGET", key, "lastTime", "curTokens")
local lastTime = ratelimitInfo[1]
local preTokens = tonumber(ratelimitInfo[2])

local realCurTokens = maxBurst;
if (type(lastTime) ~= 'boolean' and lastTime ~= nil) then
    local addTokens = math.floor((curTime - lastTime) / 1000) * rate;
    if (addTokens > 0) then
        redis.call("HSET", KEYS[1], "lastTime", curTime);
    end
    realCurTokens = math.min(addTokens + preTokens, maxBurst);
else
    redis.call("HSET", KEYS[1], "lastTime", curTime);
end

local result = 'false';
if (realCurTokens - consumeToken > 0) then
    result = 'true';
    redis.call("HSET", key, "curTokens", realCurTokens - consumeToken);
else
    redis.call("HSET", key, "curTokens", realCurTokens);
end

return result